<template>
  <div class="login_container">
    <!-- 登录对话框 -->
    <el-dialog
      v-model="showLogin"
      width="700"
      lock-scroll
      :close-on-click-modal="false"
    >
      <template #header>用户登录</template>
      <template #default>
        <el-row :gutter="20">
          <!-- 左侧手机登录/微信登录 -->
          <el-col :span="12">
            <div class="login">
              <!-- 手机号登录 -->
              <div class="phone" v-if="isPhone">
                <!-- ref用户获取form组件对象,model要校验的对象,rules校验规则 -->
                <el-form ref="formRef" :model="loginParams" :rules="rules">
                  <!-- prop要校验的属性 -->
                  <el-form-item prop="tel">
                    <el-input
                      v-model="loginParams.tel"
                      prefix-icon="PhoneFilled"
                      placeholder="请输入手机号码"
                      autocomplete
                    >
                      <!-- 输入框尾部插槽 -->
                      <template #suffix>
                        <SvgIcon
                          v-show="getCodeDisabled"
                          name="check"
                          width="14px"
                          height="14px"
                        />
                      </template>
                    </el-input>
                  </el-form-item>
                  <el-form-item prop="code">
                    <el-input
                      v-model="loginParams.code"
                      prefix-icon="Lock"
                      placeholder="请输入手机验证码"
                      :disabled="!loginParams.tel"
                    >
                      <!-- 输入框尾部插槽 -->
                      <template #suffix>
                        <SvgIcon
                          v-show="loginParams.code.length == 6"
                          name="check"
                          width="14px"
                          height="14px"
                        />
                      </template>
                    </el-input>
                  </el-form-item>
                  <el-form-item>
                    <el-button
                      :disabled="!getCodeDisabled || timeFlag"
                      size="default"
                      :loading="getCodeLoading"
                      @click="getPhoneCode"
                    >
                      <!-- timeFlag用于控制是否显示倒计时组件 -->
                      <span v-if="!timeFlag">获取验证码</span>
                      <!-- 倒计时组件 -->
                      <CountDown
                        v-else
                        :timeFlag="timeFlag"
                        @change-time="timeFlag = false"
                      />
                    </el-button>
                  </el-form-item>
                  <!-- 登录按钮 -->
                  <el-form-item>
                    <el-button
                      style="width: 100%"
                      type="primary"
                      size="default"
                      :disabled="loginParams.code.length !== 6"
                      @click="login"
                    >
                      用户登录
                    </el-button>
                  </el-form-item>
                </el-form>
              </div>
              <!-- 微信二维码登录 -->
              <div class="wx" v-else>
                <!-- 存放微信扫码登录二维码 -->
                <div id="login_container"></div>
              </div>
              <!-- 手机登录/二维码登录切换 -->
              <div class="bottom">
                <div class="change_login" @click="changeLogin">
                  <p>{{ isPhone ? '微信扫码' : '手机短信验证码' }}登录</p>
                  <SvgIcon
                    :name="isPhone ? 'weixin' : 'phone'"
                    height="25px"
                    width="25px"
                  ></SvgIcon>
                </div>
              </div>
            </div>
          </el-col>
          <!-- 右侧展示两个二维码和文字 -->
          <el-col :span="12">
            <div class="info">
              <!-- 二维码 -->
              <div class="qrCode">
                <div class="left">
                  <img
                    width="120px"
                    src="../../assets/images/code_app.png"
                    alt=""
                  />
                  <SvgIcon name="weixin"></SvgIcon>
                  <p>微信扫一扫关注</p>
                  <p>"快速预约挂号"</p>
                </div>
                <div class="right">
                  <img
                    width="120px"
                    src="../../assets/images/code_login_wechat.png"
                    alt=""
                  />
                  <SvgIcon name="phone"></SvgIcon>
                  <p>扫一扫下载</p>
                  <p>"预约挂号"APP</p>
                </div>
              </div>
              <div class="text">
                <p>官方指定平台</p>
                <p>快速挂号&nbsp;&nbsp;安全放心</p>
              </div>
            </div>
          </el-col>
        </el-row>
      </template>
      <template #footer>
        <el-button type="primary" size="default" @click="showLogin = false">
          关闭窗口
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="Login">
import { reqPhoneCode, reqWxLogin } from '@/api/login'
import useUserStore from '@/store/modules/user'
import { ElMessage, ElNotification } from 'element-plus'
import { storeToRefs } from 'pinia'
import { computed, reactive, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'

// 获取用户仓库中的数据 showLogin控制对话框的显示与隐藏
const { showLogin, userName } = storeToRefs(useUserStore())
// 从仓库中获取用户登录,查看本地存储中是否有用户信息的方法
const { userLogin, queryState } = useUserStore()
// 获取表单的ref
let formRef = ref()
// 获取路由对象
const route = useRoute()
// 获取路由器对象
const router = useRouter()
// 控制获取验证码是的加载效果
let getCodeLoading = ref(false)
// 控制倒计时的显示与隐藏
let timeFlag = ref(false)
// 控制手机号登录与微信扫码登录的切换
let isPhone = ref(true) // true:手机号登录 false:微信扫码登录
// 收集表单数据
const loginParams = reactive({
  tel: '',
  code: '',
})
// 存储正确的验证码进行验证
let trueCode = ref('')
// 计算控制获取验证码按钮是否可用(手机号码格式是否正确)
let getCodeDisabled = computed(() =>
  /^(?:(?:\+|00)86)?1\d{10}$/.test(loginParams.tel),
)

// 进行表单验证，当手机号满足条件时，才能获取验证码
const rules = reactive({
  tel: [
    // 要校验的属性值
    {
      required: true, // 必须校验
      message: '手机号不能为空', // 校验不通过提示信息
      trigger: 'change', // 触发校验的时机 change:文本发生变化,blur:失焦时触发
    },
    {
      pattern: /^(?:(?:\+|00)86)?1\d{10}$/, // 正则校验
      message: '手机号格式不正确',
      trigger: 'change',
    },
  ],
  code: [
    {
      required: true,
      message: '请输入验证码',
      trigger: 'change',
    },
    {
      pattern: /^[0-9]{6}$/, // 正则校验
      message: '验证码为6位数字',
      trigger: 'change',
    },
  ],
})
// 点击获取手机验证码的回调
const getPhoneCode = async () => {
  // 开启加载效果
  getCodeLoading.value = true
  // 开始倒计时
  timeFlag.value = true
  // 获取验证码
  let result = await reqPhoneCode(loginParams.tel)
  if (result.code === 200) {
    // 存储验证码
    trueCode.value = result.data
    loginParams.code = result.data
    // 关闭加载效果
    getCodeLoading.value = false
  } else {
    ElMessage.error('获取验证码失败')
  }
}
// 点击切换登录方式的回调
const changeLogin = async () => {
  // 切换显示的页面
  isPhone.value = !isPhone.value
  // 当切换到二维码登录页面
  if (isPhone.value == false) {
    // 发请求获取微信扫码需要的参数
    // 需要携带一个参数:告诉服务器用户授权成功后重定向项目的指定页面(服务器会将用户信息注入该页面)
    let wxRedirectUri = encodeURIComponent(window.location.origin + '/wxlogin') // 需要对Uri进行编码
    let result = await reqWxLogin(wxRedirectUri)
    // 生成微信扫码登录的二维码页面
    // @ts-ignore
    new WxLogin({
      self_redirect: true, //true:手机点击确定后可以在iframe内跳转到redirect_url
      id: 'login_container', // 显示二维码的容器
      appid: result.data.appid, // 应用的唯一标识,在微信开发平台申请用户成功后获取
      scope: 'snsapi_login', // 应用授权的作用域,网页引用目前仅需填写snsapi_login
      redirect_uri: result.data.redirectUri, // 授权回调域,用户授权成功后微信服务器向此地址发送code参数
      state: result.data.state, // 应用服务器重定向的地址,用户点击后跳转的地址,携带用户信息参数
      style: 'black', // 二维码样式,黑色/白色
      href: '', // 自定义二维码样式链接
    })
    // 查看本地存储是否有数据,判断用户是否授权登录成功
    queryState()
  } else {
    // 清除上次输入的数据
    Object.assign(loginParams, {
      tel: '',
      code: '',
    })
  }
}
// 点击登录按钮的回调
const login = async () => {
  // 进行表单验证，验证通过才能发请求获取用户数据
  await formRef.value.validate()
  // 验证码验证
  if (loginParams.code !== trueCode.value) {
    ElMessage.error('验证码错误')
    return
  }
  // 发请求 userLogin为一个async函数 返回成功/失败的Promise对象
  try {
    // await必须等待userLogin返回成功的Promise对象
    await userLogin({
      phone: loginParams.tel,
      code: loginParams.code,
    })
    // 请求成功关闭登录弹窗
    showLogin.value = false
    // 显示欢迎提示
    ElNotification({
      type: 'success',
      title: '欢迎登录尚医通',
      message: '用户：' + userName.value,
    })
    // 如果当前路由对象有query参数redirect则跳转到该路由
    /* if (route.query.redirect) {
      router.push(route.query.redirect as string)
    } else {
      // 跳转到首页
      router.push('/')
    } */
    router.push(route.query.redirect ? (route.query.redirect as string) : '/')
  } catch (error) {
    // 请求失败
    ElMessage.error('验证码错误')
  }
}
</script>

<style scoped lang="scss">
:deep(.el-dialog__header.show-close) {
  border-bottom: 1px solid rgb(230, 230, 230);
  font-size: 20px;
  color: $base-active-color;
}
:deep(.el-dialog__footer) {
  border-top: 1px solid rgb(230, 230, 230);
}
:deep(.el-dialog__body) {
  margin: 30px 10px;
}
.login {
  border: 1px solid rgb(230, 230, 230);
  border-radius: 5px;
  padding: 20px;
  color: $base-color;
  .wx {
    display: flex;
    justify-content: center;
    align-items: center;
    // #login_container {
    //   transform: scale(0.8);
    // }
  }
  .bottom {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    cursor: pointer;
    .change_login {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      p {
        margin-bottom: 8px;
        margin-top: -4px;
      }
    }
  }
}
.info {
  .qrCode {
    display: flex;
    justify-content: space-around;
    .left,
    .right {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      text-align: center;
      p {
        line-height: 20px;
      }
    }
  }
  .text {
    text-align: center;
    color: $base-active-color;
    font-size: 25px;
    font-style: italic;
    margin-top: 20px;
    p {
      line-height: 40px;
    }
  }
}
</style>
